package org.galagosearch.core.scoring;

import java.io.IOException;
import org.galagosearch.core.retrieval.structured.CountIterator;
import org.galagosearch.core.retrieval.structured.RequiredStatistics;
import org.galagosearch.core.retrieval.structured.ScoringFunctionIterator;
import org.galagosearch.tupleflow.Parameters;
/*
 * author:irmarc
 * modified by:Tejas
 */

@RequiredStatistics(statistics = {"collectionLength","documentCount"})
public class BM25Scorer extends ScoringFunctionIterator {
	double b;
    double k;
    double avgDocLength;
    double idf;
    
	public BM25Scorer(Parameters parameters, CountIterator iterator) throws IOException {
	        super(iterator);

	        b = parameters.get("b", 0.75D);
	        k = parameters.get("k", 1.2D);

	        long collectionLength = parameters.get("collectionLength", 0L);
	        long documentCount = parameters.get("documentCount", 0L);
	        avgDocLength = (collectionLength + 0.0) / (documentCount + 0.0);

	        // now get idf
	        long df = 0;
	        if (parameters.containsKey("df")) {
	            df = parameters.get("df", 0L);
	        } else {
	        	
	        	while (!iterator.isDone()) {
	                 df=(iterator.count()>0?df+1:df); //number of documents that contain this terms' iterator
	                iterator.nextDocument();
	            }
	        }
	        idf = Math.log((documentCount - df + 0.5) / (df + 0.5));
    }
	@Override
	public double scoreCount(int count, int length) {
		// TODO Auto-generated method stub
		double numerator = count * (k + 1);
        double denominator = count + (k * (1 - b + (b * length / avgDocLength)));
        return idf * numerator / denominator;
	}
}

